
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

#include "posthack.h"

// Local prototypes
void Hexa (char *, const float);

std::vector<char> * PSCharArray (float *data, int nx, int ny, 
				 float fmin, float fmax, 
				 float **RGB, float* RGB_val, int nRGB)
{
  std::vector<char> *res = new std::vector<char>;
  char ch[2];

  for (int j=0; j<ny; j++) 
    for (int i = 0; i<nx; i++) {
      int k;
      float val = (data[i+j*nx] - fmin)/(fmax-fmin);

      float r = RGB[0][nRGB-1];
      float g = RGB[1][nRGB-1];
      float b = RGB[2][nRGB-1];

      for (k=0; k<nRGB; k++) {
	if (val < RGB_val[k]) {
	  if (k==0) {
	    r = RGB[0][0];
	    g = RGB[1][0];
	    b = RGB[2][0];
	  }
	  else {
	    float frac = (val - RGB_val[k-1])/(RGB_val[k]-RGB_val[k-1]);
	    r = RGB[0][k-1] + (RGB[0][k]-RGB[0][k-1])*frac;
	    g = RGB[1][k-1] + (RGB[1][k]-RGB[1][k-1])*frac;
	    b = RGB[2][k-1] + (RGB[2][k]-RGB[2][k-1])*frac;
	  }
	  break;
	}
      }
      Hexa (&ch[0], r);
      res->push_back (ch[0]);
      res->push_back (ch[1]);
      Hexa (&ch[0], g);
      res->push_back (ch[0]);
      res->push_back (ch[1]);
      Hexa (&ch[0], b);
      res->push_back (ch[0]);
      res->push_back (ch[1]);
      

    }  
  return (res);
}

std::vector<char> * PSCharArray3 (int nx, int ny,
				  float *rdata, float rfmin, float rfmax, 
				  float *gdata, float gfmin, float gfmax, 
				  float *bdata, float bfmin, float bfmax, 
				  float **RGB, float* RGB_val, int nRGB)
{
  std::vector<char> *res = new std::vector<char>;
  char ch[2];

  for (int j=0; j<ny; j++) 
    for (int i = 0; i<nx; i++) {
      int k;
      float rval = (rdata[i+j*nx] - rfmin)/(rfmax-rfmin);
      float gval = (gdata[i+j*nx] - gfmin)/(gfmax-gfmin);
      float bval = (bdata[i+j*nx] - bfmin)/(bfmax-bfmin);

      float r = RGB[0][nRGB-1];
      float g = RGB[1][nRGB-1];
      float b = RGB[2][nRGB-1];

      for (k=0; k<nRGB; k++) {
	if (rval < RGB_val[k]) {
	  if (k==0) 
	    r = RGB[0][0];
	  else {
	    float frac = (rval - RGB_val[k-1])/(RGB_val[k]-RGB_val[k-1]);
	    r = RGB[0][k-1] + (RGB[0][k]-RGB[0][k-1])*frac;
	  }
	  break;
	}
      }

      for (k=0; k<nRGB; k++) {
	if (gval < RGB_val[k]) {
	  if (k==0) 
	    g = RGB[1][0];
	  else {
	    float frac = (gval - RGB_val[k-1])/(RGB_val[k]-RGB_val[k-1]);
	    g = RGB[1][k-1] + (RGB[1][k]-RGB[1][k-1])*frac;
	  }
	  break;
	}
      }

      for (k=0; k<nRGB; k++) {
	if (bval < RGB_val[k]) {
	  if (k==0) 
	    b = RGB[2][0];
	  else {
	    float frac = (bval - RGB_val[k-1])/(RGB_val[k]-RGB_val[k-1]);
	    b = RGB[2][k-1] + (RGB[2][k]-RGB[2][k-1])*frac;
	  }
	  break;
	}
      }

      Hexa (&ch[0], r);
      res->push_back (ch[0]);
      res->push_back (ch[1]);
      Hexa (&ch[0], g);
      res->push_back (ch[0]);
      res->push_back (ch[1]);
      Hexa (&ch[0], b);
      res->push_back (ch[0]);
      res->push_back (ch[1]);
      

    }  
  return (res);
}


void InsertPSCharArray (const char *filename, std::vector<char> *arr,
			const char *comm)
{
  struct stat ls_buf;
  if (lstat (filename, &ls_buf) == 0) {
    char *buf = new char[ls_buf.st_size+1];
    FILE * file = fopen (filename, "r");
    fread (buf, ls_buf.st_size, 1, file);
    fclose (file);
    buf[ls_buf.st_size] = 0;

    char *pos = strstr (buf, "colorimage");
    if (pos!= NULL) {
      char *pos1 = strstr (pos, "grestore");
      if (pos1 != NULL) {
	file = fopen (filename, "w");
	fwrite (buf, pos-buf+strlen("colorimage\n"), 1, file);
	unsigned int i = 0;
	int j=0;
	while (i<arr->size()) {
	  fprintf (file,"%c", (*arr)[i]);
	  i++;
	  j++;
	  if (j==120) {
	    fprintf (file,"\n");
	    j=0;
	  }
	}
	if (j!=120)
	  fprintf (file,"\n");

	fprintf (file, "%s",pos1);
	if (comm!=NULL) {
	  int nnn = 0;
	  while (nnn<strlen(comm)) {
	    fprintf (file, "%%%%%75s\n", &comm[nnn]);
	    nnn = nnn+75;
	  }
	}
	fclose (file);
      }
      else
	fprintf (stderr, "WARNING: pos1 not found\n");
    }
    else
      fprintf (stderr, "WARNING: pos not found\n");
    delete [] buf;
  }
  else
    fprintf (stderr, "WARNING: cannot lstat file\n");
}


void Hexa (char *res, const float val)
{
  if (val<0.0 && val > 1.0) {
    res[0] = '0';
    res[1] = '1';
  }
  else {
    int ival = (int)(255.0 * val);
    int uval = ival/16;
    int lval = ival%16;
    switch (uval) {
    case 15:
      res[0] = 'F';
      break;
    case 14:
      res[0] = 'E';
      break;
    case 13:
      res[0] = 'D';
      break;
    case 12:
      res[0] = 'C';
      break;
    case 11:
      res[0] = 'B';
      break;
    case 10:
      res[0] = 'A';
      break;
    case 9:
      res[0] = '9';
      break;
    case 8:
      res[0] = '8';
      break;
    case 7:
      res[0] = '7';
      break;
    case 6:
      res[0] = '6';
      break;
    case 5:
      res[0] = '5';
      break;
    case 4:
      res[0] = '4';
      break;
    case 3:
      res[0] = '3';
      break;
    case 2:
      res[0] = '2';
      break;
    case 1:
      res[0] = '1';
      break;
    case 0:
      res[0] = '0';
      break;
    }

    switch (lval) {
    case 15:
      res[1] = 'F';
      break;
    case 14:
      res[1] = 'E';
      break;
    case 13:
      res[1] = 'D';
      break;
    case 12:
      res[1] = 'C';
      break;
    case 11:
      res[1] = 'B';
      break;
    case 10:
      res[1] = 'A';
      break;
    case 9:
      res[1] = '9';
      break;
    case 8:
      res[1] = '8';
      break;
    case 7:
      res[1] = '7';
      break;
    case 6:
      res[1] = '6';
      break;
    case 5:
      res[1] = '5';
      break;
    case 4:
      res[1] = '4';
      break;
    case 3:
      res[1] = '3';
      break;
    case 2:
      res[1] = '2';
      break;
    case 1:
      res[1] = '1';
      break;
    case 0:
      res[1] = '0';
      break;
    default:
      res[1] = lval;
      break;
    }
  }
}
